using System;
namespace CSUtils {
    public class CMathf {
        public static float Range(float r1, float r2) {
            return(r1 + r2) * 0.5f;
        }

        public static int FloorToInt(float f) {
            return(int)Math.Floor((double)f);
        }

        /// <summary>
        /// 四舍五入到整数
        /// </summary> 
        public static int RoundToInt(float f)=>(int)Math.Round((double)f);

        public static float Lerp(float a, float b, float t) {
            return a + (b - a) * CMathf.Clamp01(t);
        }

        public static float LerpUnclamped(float a, float b, float t)=>a + (b - a) * t;
        public static float Repeat(float t, float length)=>CMathf.Clamp(t - CMathf.Floor(t / length) * length, 0.0f, length);

        /// <summary>
        ///   <para>Same as Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.</para>
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="t"></param>
        public static float LerpAngle(float a, float b, float t) {
            float num = CMathf.Repeat(b - a, 360f);
            if((double)num > 180.0)
                num -= 360f;
            return a + num * CMathf.Clamp01(t);
        }

        public static float Clamp01(float value) {
            if((double)value < 0.0)
                return 0.0f;
            return(double)value > 1.0? 1f: value;
        }

        public static float Clamp(float value, float min, float max) {
            if((double)value < (double)min)
                value = min;
            else if((double)value > (double)max)
                value = max;
            return value;
        }

        public static int Clamp(int value, int min, int max) {
            if(value < min)
                value = min;
            else if(value > max)
                value = max;
            return value;
        }

        public static float Log10(float f)=>(float)Math.Log10((double)f);

        /// <summary>
        ///   <para>Returns the smallest integer greater to or equal to f.</para>
        /// </summary>
        /// <param name="f"></param>
        public static float Ceil(float f)=>(float)Math.Ceiling((double)f);

        /// <summary>
        ///   <para>Returns the largest integer smaller than or equal to f.</para>
        /// </summary>
        /// <param name="f"></param>
        public static float Floor(float f)=>(float)Math.Floor((double)f);

        /// <summary>
        ///   <para>Returns f rounded to the nearest integer.</para>
        /// </summary>
        /// <param name="f"></param>
        public static float Round(float f)=>(float)Math.Round((double)f);

        /// <summary>
        ///   <para>Returns the smallest integer greater to or equal to f.</para>
        /// </summary>
        /// <param name="f"></param>
        public static int CeilToInt(float f)=>(int)Math.Ceiling((double)f);
    }
}
